﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PremisPublisher.ViewModel
{
    #region 额外的库引用
    using System.Configuration;
    using GalaSoft.MvvmLight;
    using System.Windows.Input;
    using GalaSoft.MvvmLight.Command;
    using GalaSoft.MvvmLight.Messaging;
    using DataTransferForWCFHelper;
    using Layer;
    using IPRMIS_U_Contract;
    using System.Windows.Threading;
    using Xceed.Wpf.Toolkit;
    using Microsoft.SqlServer.Management.Smo;
    using System.IO;
    using System.Data;
    using System.ComponentModel;
    using System.Windows.Controls;
    using System.Collections.ObjectModel;
    using PremisPublisher;
    using PremisPublisher.Messages;
    using PremisPublisher.Common;
    #endregion



    /*
     
     项目升级主Model（sql文件执行）
     * 
     * 作者：张鹏
     * 日期：2016.5
     
     */


    public class UpgradeMainViewModel : ViewModelBase
    {
        //private string title;

        //public string Title
        //{
        //    get { return title; }
        //    set { title = value; RaisePropertyChanged("Title"); }
        //}


        /// <summary>
        /// rsa解密公钥
        /// </summary>
        private const string rsa_private_key = @"<RSAKeyValue><Modulus>5m9m14XH3oqLJ8bNGw9e4rGpXpcktv9MSkHSVFVMjHbfv+SJ5v0ubqQxa5YjLN4vc49z7SVju8s0X4gZ6AzZTn06jzWOgyPRV54Q4I0DCYadWW4Ze3e+BOtwgVU1Og3qHKn8vygoj40J6U85Z/PTJu3hN1m75Zr195ju7g9v4Hk=</Modulus><Exponent>AQAB</Exponent><P>/hf2dnK7rNfl3lbqghWcpFdu778hUpIEBixCDL5WiBtpkZdpSw90aERmHJYaW2RGvGRi6zSftLh00KHsPcNUMw==</P><Q>6Cn/jOLrPapDTEp1Fkq+uz++1Do0eeX7HYqi9rY29CqShzCeI7LEYOoSwYuAJ3xA/DuCdQENPSoJ9KFbO4Wsow==</Q><DP>ga1rHIJro8e/yhxjrKYo/nqc5ICQGhrpMNlPkD9n3CjZVPOISkWF7FzUHEzDANeJfkZhcZa21z24aG3rKo5Qnw==</DP><DQ>MNGsCB8rYlMsRZ2ek2pyQwO7h/sZT8y5ilO9wu08Dwnot/7UMiOEQfDWstY3w5XQQHnvC9WFyCfP4h4QBissyw==</DQ><InverseQ>EG02S7SADhH1EVT9DD0Z62Y0uY7gIYvxX/uq+IzKSCwB8M2G7Qv9xgZQaQlLpCaeKbux3Y59hHM+KpamGL19Kg==</InverseQ><D>vmaYHEbPAgOJvaEXQl+t8DQKFT1fudEysTy31LTyXjGu6XiltXXHUuZaa2IPyHgBz0Nd7znwsW/S44iql0Fen1kzKioEL3svANui63O3o5xdDeExVM6zOf1wUUh/oldovPweChyoAdMtUzgvCbJk1sYDJf++Nr0FeNW1RB1XG30=</D></RSAKeyValue>";

        /// <summary>
        /// sqlserver smo sdk 的 server, 执行sql脚本用
        /// </summary>
        static Server srv;


        private List<string> _user_domains;

        /// <summary>
        /// 业务代码列表
        /// </summary>
        public List<string> UserDomains
        {
            get { return _user_domains; }
            set { _user_domains = value; RaisePropertyChanged("UserDomains"); }
        }

        private bool _busying;

        /// <summary>
        /// 进度条组件状态
        /// </summary>
        public bool Busying
        {
            get { return _busying; }
            set { _busying = value; RaisePropertyChanged("Busying"); }
        }

        private String busyingText;

        /// <summary>
        /// 进度条组件文字提示
        /// </summary>
        public String BusyingText
        {
            get { return busyingText; }
            set { busyingText = value; RaisePropertyChanged("BusyingText"); }
        }

        private string _name;

        /// <summary>
        /// 客户端名（从 .config 配置文件读取）
        /// </summary>
        public string Name
        {
            get { return _name; }
            set { _name = value; RaisePropertyChanged("Name"); }
        }


        private string _code;

        /// <summary>
        /// 客户端代码（从 .config 配置文件读取）
        /// </summary>
        public string Code
        {
            get { return _code; }
            set { _code = value; RaisePropertyChanged("Code"); }
        }

        /// <summary>
        /// 升级
        /// </summary>
        public ICommand UpgradeToNewVersionCommand { get; set; }

        /// <summary>
        /// 获取oper_class表中的内容
        /// </summary>
        public ICommand GetDomainInfomationsCommand { get; set; }

        /// <summary>
        /// 加密目录内的sql文件
        /// </summary>
        public ICommand CryptDirectoryFilesCommand { get; set; }


        public ICommand AllUnSelectedCommand { get; set; }

        public UpgradeMainViewModel()
        {
            var connectionString = System.Configuration.ConfigurationManager.AppSettings.Get("connstr");
            srv = new Server(new Microsoft.SqlServer.Management.Common.ServerConnection(new System.Data.SqlClient.SqlConnection(connectionString)));


            UserDomains = new List<string>();
            LoadInfo();
            UpgradeToNewVersionCommand = new RelayCommand(UpgradeToNewVersion);
            GetDomainInfomationsCommand = new RelayCommand(GetDomainInfomations);
            CryptDirectoryFilesCommand = new RelayCommand(CryptDirectoryFiles);
            AllUnSelectedCommand = new RelayCommand(AllUnSelected);

            //注册消息，接收用户选择的业务代码如H0101
            Messenger.Default.Register<string>(this, str =>
            {
                UserDomains.Add(str);
            });

            Messenger.Default.Register<GetSQLContentMessage>(this, m =>
            {
                var domain_code = m.Message;
                UpgradeMessage msg = new UpgradeMessage();

                if (domain_code.Length == 5 && "HSOTG".Contains(domain_code.Substring(0, 1)))
                {
                    ServiceCaller.TcpServiceDispatcher<IBusinessUpgrade>("0099", (svc) =>
                   {
                       msg.Name = Name;
                       msg.Code = Code;
                       msg.Message = domain_code;
                       msg = svc.Upgrade(msg);
                   });

                    switch (msg.Code)
                    {
                        case "200":
                            var sql_content = msg.Message;
                            //rsa解密
                            sql_content = RSACrypto.Decrypt(sql_content, rsa_private_key);
                            Messenger.Default.Send(new EditSQLContentMessage() { Content = sql_content, Title = domain_code });
                            break;
                        case "404":
                            Messenger.Default.Send(new ShowMessageDialogMessage() { Message = msg.Message });
                            break;
                        default:
                            Messenger.Default.Send(new ShowMessageDialogMessage() { Message = "服务器返回未知代码，请联系开发人员" });
                            break;
                    }
                }
            });
        }

        private void AllUnSelected()
        {
            DispatchService.Invoke(() =>
            {
                UserDomains.Clear();

                Messenger.Default.Send(new ClearUserDomainsMessage());
            });
        }

        private void CryptDirectoryFiles()
        {
            Messenger.Default.Send(new ShowCryptWindowMessage() { Message = "选择目录批量加密" });
        }

        private void GetDomainInfomations()
        {
            BusyingText = "获取升级信息...";
            Busying = true;

            BackgroundWorker worker = new BackgroundWorker();
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            worker.DoWork += worker_DoWork;
            worker.WorkerReportsProgress = true;

            UpgradeMessage msg = new UpgradeMessage();

            worker.RunWorkerAsync(msg);
        }

        private void UpgradeToNewVersion()
        {
            Messenger.Default.Send(new ShowPublishLogWindowMessage() { Message = "升级日志" });

            BusyingText = "正在进行升级...";
            Busying = true;

            BackgroundWorker upgradeWorker = new BackgroundWorker();
            upgradeWorker.RunWorkerCompleted += upgradeWorker_RunWorkerCompleted;
            upgradeWorker.DoWork += upgradeWorker_DoWork;
            upgradeWorker.WorkerReportsProgress = true;
            upgradeWorker.ProgressChanged += upgradeWorker_ProgressChanged;
            UpgradeMessage msg = new UpgradeMessage();
            upgradeWorker.RunWorkerAsync(msg);
        }

        void upgradeWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            BusyingText = string.Format("{0} 升级完成，当前进度: {1}%", e.UserState.ToString(), e.ProgressPercentage);
        }

        void upgradeWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            var msg = e.Argument as UpgradeMessage;

            int i = 0;

            srv.ConnectionContext.BeginTransaction();

            try
            {
                this.UserDomains.ForEach(domain_code =>
                {
                    string log_line = string.Empty;
                    if (domain_code.Length == 5 && "HSOTG".Contains(domain_code.Substring(0, 1)))
                    {
                        ServiceCaller.TcpServiceDispatcher<IBusinessUpgrade>("0099", (svc) =>
                        {
                            msg.Name = Name;
                            msg.Code = Code;
                            msg.Message = domain_code;
                            msg = svc.Upgrade(msg);
                        });

                        switch (msg.Code)
                        {
                            case "200":
                                var sql_content = msg.Message;
                                //rsa解密
                                sql_content = RSACrypto.Decrypt(sql_content, rsa_private_key);

                                var sql_result = srv.ConnectionContext.ExecuteNonQuery(sql_content,
                                    Microsoft.SqlServer.Management.Common.ExecutionTypes.Default);

                                log_line = string.Format("{0} 执行完成，结果代码：{1}", domain_code, sql_result);
                                break;
                            case "404":
                                log_line = string.Format("服务器返回消息：{0}", msg.Message);
                                break;
                            default:
                                log_line = "服务器返回未知代码，请联系开发人员";
                                break;
                        }

                        int percent = (int)(((double)i++ / (double)((long)this.UserDomains.Count)) * 100);
                        (sender as BackgroundWorker).ReportProgress(percent, domain_code);

                    }
                    else
                    {
                        log_line = "非法的业务代码";
                    }
                    Messenger.Default.Send(new PublishLogMessage() { Message = log_line });
                });
                srv.ConnectionContext.CommitTransaction();
            }

            catch (Exception ex)
            {
                srv.ConnectionContext.RollBackTransaction();
                Messenger.Default.Send(new PublishLogMessage() { Message = ex.InnerException.Message });
                Messenger.Default.Send(new PublishLogMessage() { Message = ex.Message });
            }
        }

        void upgradeWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Busying = false;
        }

        private void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            var msg = e.Argument as UpgradeMessage;

            try
            {
                ServiceCaller.TcpServiceDispatcher<IBusinessUpgrade>("0099", (svc) =>
                {
                    msg.Name = Name;
                    msg.Code = Code;
                    msg = svc.DomainQuery(msg);
                    BusyingText = msg.Message;
                    e.Result = msg;
                });
            }
            catch (Exception ex)
            {
                Messenger.Default.Send(new PublishLogMessage() { Message = ex.Message });
                if (ex.InnerException != null)
                    Messenger.Default.Send(new PublishLogMessage() { Message = ex.InnerException.Message });
            }
        }

        private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Busying = false;
            var msg = e.Result as UpgradeMessage;

            if (msg != null && msg.Domains != null)
                //将获取到的DataSet发送到Xaml.cs中的binding 数据源中
                Messenger.Default.Send(msg.Domains);
            else
                Messenger.Default.Send(new ShowMessageDialogMessage() { Message = msg.Message });
        }

        public void LoadInfo()
        {
            Name = ConfigurationManager.AppSettings.Get("Name");
            Code = ConfigurationManager.AppSettings.Get("Code");
        }
    }
}
